package com.vtuzx.kingdee.xqc_core.dao;

import com.mongodb.client.MongoCursor;
import com.vtuzx.core.bean.dto.VtuzxPage;
import com.vtuzx.core.db.mongo.impl.VtuzxDaoImpl;
import com.vtuzx.core.utils.VtuzxUtil;
import com.vtuzx.kingdee.xqc_core.bean.VtuzxArrayList;
import com.vtuzx.kingdee.xqc_core.constant.BillStatus;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

@Component
public class PrdTaskDao extends VtuzxDaoImpl {
    /** 集合名称 */
    public static final String NAME = "t_prd_task";

    public PrdTaskDao() {
        super(NAME);
    }

    /**
     * 新建单据
     *
     * @param _userId 用户ID
     * @param userName 用户名
     * @param doc 数据
     * @return 单据ID
     */
    public ObjectId insertBill(ObjectId _userId, String userName, Document doc) {
        doc.append("_createUserId", _userId);
        doc.append("createUserName", userName);
        doc.append("_updateUserId", _userId);
        doc.append("updateUserName", userName);
        return insertOne(doc);
    }

    /**
     * 审批单据
     *
     * @param _userId 用户ID
     * @param userName 用户名
     * @param billNo 数据编号
     */
    public void audit(ObjectId _userId, String userName, String billNo) {
        updateOne(Criteria.where("billNo").is(billNo),
                new Document("status", BillStatus.Audit.toString())
                        .append("auditTime", new Date())
                        .append("_auditUserId", _userId)
                        .append("auditUserName", userName));
    }

    /**
     * 反审批单据
     *
     * @param billNo 数据编号
     */
    public void unaudit(String billNo) {
        updateOne(Criteria.where("billNo").is(billNo), new Document("status", BillStatus.Save.toString()));
    }

    /**
     * 获取单据详细
     *
     * @param cond 检索条件
     */
    public Iterator<Document> findShowList(Criteria cond, Document sort, int skip, int limit) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$sort", sort));
        docList.add(new Document("$skip", skip));
        docList.add(new Document("$limit", limit));
        docList.add(new Document("$lookup", new Document("from", PurOrderDetailDao.NAME).append("foreignField", "orderNo").append("localField", "orderNo").append("as", "detail")));
        return this.aggregate(docList);
    }

    /**
     * 获取单据详细
     *
     * @param cond 检索条件
     */
    public Iterator<Document> findPurOrderList(Criteria cond) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$lookup", new Document("from", PurOrderDetailDao.NAME).append("foreignField", "orderNo").append("localField", "orderNo").append("as", "detail")));
        docList.add(new Document("$unwind", new Document("path", "$detail").append("preserveNullAndEmptyArrays", true)));
        docList.add(new Document("$lookup", new Document("from", PurSettlementDao.NAME).append("foreignField", "_detailId").append("localField", "detail._id").append("as", "settlement")));
        docList.add(new Document("$unwind", new Document("path", "$settlement").append("preserveNullAndEmptyArrays", true)));
        docList.add(new Document("$sort", new Document("createTime", -1).append("detail._id", 1).append("settlement.create", -1)));
        return this.aggregate(docList);
    }
    //用于生产审核分页
    public Iterator<Document> prdTaskPage(Criteria cond, Document sort, int pageIndex, int pageSize) {
        List<Document> docList = new ArrayList<>();
        //docList.add(new Document("$lookup", new Document("from", PrdTaskDetailDao.NAME).append("foreignField", "_inventoryId").append("localField", "_id").append("as", "prdTaskDetail")));
        docList.add(new Document("$match", cond.getCriteriaObject()));
        if (sort != null) {
            docList.add(new Document("$sort", sort));
        }
        if (pageIndex > 0 && pageSize > 0) {
            docList.add(new Document("$skip", pageIndex * pageSize));
        }
        if (pageSize > 0) {
            docList.add(new Document("$limit", pageSize));
        }
        return this.aggregate(docList);
    }
    //计算生产任务总数量
    public int prdTaskCount(Criteria cond) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$match", cond.getCriteriaObject()));
        docList.add(new Document("$group",
                new Document("_id", null).append("count", new Document("$sum", 1))));
        Iterator<Document> itr = this.aggregate(docList);
        if (itr.hasNext()) {
            return VtuzxUtil.getObject(itr.next(), "count");
        }
        return 0;
    }

    public VtuzxPage getPageList(Criteria cond, Document sort, int pageIndex, int pageSize) {
        Document project = new Document("_id", 1);

        List<Document> countDocList = new ArrayList<>();
        countDocList.add(new Document("$match", cond));
        countDocList.add(new Document("$group", new Document("_id", null).append("total", new Document("$sum", 1))));
        Iterator<Document> countItr = this.aggregate(countDocList);
        long total = 0;
        if (countItr.hasNext()) {
            Document totalDoc = countItr.next();
            total = VtuzxUtil.getLong(totalDoc, "total");
        }
        if (total == 0) {
            return new VtuzxPage(0, null);
        }
        List<Document> dataDocList = new ArrayList<>();
        dataDocList.add(new Document("$match", cond));
        dataDocList.add(new Document("$sort", new Document("createTime", -1)));
        dataDocList.add(new Document("$skip", pageIndex * pageSize));
        dataDocList.add(new Document("$limit", pageSize));
        Iterator<Document> dataItr = this.aggregate(dataDocList);

        return new VtuzxPage(total, dataItr);
    }

    /**
     * 查询领料,补料,入库信息(损耗率)
     * @param cond
     * @param sort
     * @param pageIndex
     * @param pageSize
     * @return
     */
    public Iterator<Document> getTaskLoss(Criteria cond, Document sort, int pageIndex, int pageSize) {
        List<Document> docList = new ArrayList<>();
        docList.add(new Document("$group", new Document("_id", "any")
                .append(MaterialBomPickDao.NAME, new Document("$push","$$ROOT"))));
        docList.add(new Document("$lookup", new Document("from",
                MaterialBomSupplementDao.NAME).append("foreignField", "xxx1")
                .append("localField", "xxx2").append("as", MaterialBomSupplementDao.NAME)));
        docList.add(new Document("$lookup", new Document("from", PrdInDao.NAME).append("foreignField", "xxx1").append("localField", "xxx2").append("as", PrdInDao.NAME)));

        docList.add(new Document("$project", new Document("_id", null).append("allValue", new Document("$setUnion", new VtuzxArrayList<>( "$" + MaterialBomPickDao.NAME,"$"+MaterialBomSupplementDao.NAME,
                "$"+PrdInDao.NAME)))));
        docList.add(new Document("$unwind", new Document("path", "$allValue")));
        docList.add(new Document("$match", cond.getCriteriaObject()));
        if ( sort != null){
            docList.add(new Document("$sort",sort));
        }
        if (pageIndex > 0 && pageSize > 0) {
            docList.add(new Document("$skip", pageIndex * pageSize));
        }
        if (pageSize > 0) {
            docList.add(new Document("$limit", pageSize));
        }
        return this.aggregate(docList);
    }

    /**
     * 查询b的订单(领料或者补料包含bn的)
     * @param cond
     * @param sort
     * @param pageIndex
     * @param pageSize
     * @return
     */
    public Iterator<Document> getBnTask(Criteria cond, Document sort, int pageIndex, int pageSize) {
        List<Document> pipeline = new ArrayList<>();
        // 1. 构建 $match
        Document match = new Document("$match", cond.getCriteriaObject());
        pipeline.add(match);

        // 2. 构建 $sort（默认 createTime 倒序）
        Document sortDoc = sort != null ? sort : new Document("createTime", -1);
        pipeline.add(new Document("$sort", sortDoc));

        // 3. 构建 $skip 和 $limit 实现分页
        pipeline.add(new Document("$skip", pageIndex * pageSize));
        pipeline.add(new Document("$limit", pageSize));

        // 4. $lookup 关联 materialBomPickDetailDao
        Document lookupPick = new Document("$lookup", new Document()
                .append("from", MaterialBomPickDetailDao.NAME)
                .append("localField", "billNo")
                .append("foreignField", "taskBillNo")
                .append("as", "pickDetails")
        );
        pipeline.add(lookupPick);

        // 5. $lookup 关联 materialBomSupplementDetailDao
        Document lookupSupplement = new Document("$lookup", new Document()
                .append("from", MaterialBomSupplementDetailDao.NAME)
                .append("localField", "billNo")
                .append("foreignField", "taskBillNo")
                .append("as", "supplementDetails")
        );
        pipeline.add(lookupSupplement);

        // 6. 执行聚合查询
        Iterator<Document> cursor = this.aggregate(pipeline);

        return cursor;
    }
}
